/**
 * 性能监控工具
 * Performance Monitoring Utilities
 */

const os = require('os');
const fs = require('fs');
const path = require('path');
const logger = require('./logger');

class PerformanceMonitor {
  constructor() {
    this.metrics = {
      requests: {
        total: 0,
        successful: 0,
        failed: 0,
        averageResponseTime: 0
      },
      memory: {
        used: 0,
        free: 0,
        total: 0,
        percentage: 0
      },
      cpu: {
        usage: 0,
        loadAverage: []
      },
      database: {
        activeConnections: 0,
        totalQueries: 0,
        averageQueryTime: 0,
        slowQueries: 0
      },
      storage: {
        used: 0,
        free: 0,
        total: 0,
        percentage: 0
      }
    };

    this.requestTimes = [];
    this.queryTimes = [];
    this.startTime = Date.now();
    this.alertThresholds = {
      memoryUsage: 80, // 80%
      cpuUsage: 80,    // 80%
      responseTime: 5000, // 5秒
      storageUsage: 90 // 90%
    };

    // 定期收集系统指标
    this.startMetricsCollection();
  }

  /**
   * 开始指标收集
   */
  startMetricsCollection() {
    // 每30秒收集一次系统指标
    setInterval(() => {
      this.collectSystemMetrics();
    }, 30000);

    // 每5分钟清理旧的请求时间数据
    setInterval(() => {
      this.cleanupOldMetrics();
    }, 5 * 60 * 1000);
  }

  /**
   * 收集系统指标
   */
  collectSystemMetrics() {
    try {
      // 内存使用情况
      const memInfo = process.memoryUsage();
      const totalMem = os.totalmem();
      const freeMem = os.freemem();
      const usedMem = totalMem - freeMem;

      this.metrics.memory = {
        used: usedMem,
        free: freeMem,
        total: totalMem,
        percentage: (usedMem / totalMem) * 100,
        heap: {
          used: memInfo.heapUsed,
          total: memInfo.heapTotal,
          external: memInfo.external
        }
      };

      // CPU使用情况
      const cpus = os.cpus();
      this.metrics.cpu = {
        count: cpus.length,
        loadAverage: os.loadavg(),
        usage: this.calculateCpuUsage()
      };

      // 存储使用情况
      this.collectStorageMetrics();

      // 检查警告阈值
      this.checkAlertThresholds();

    } catch (error) {
      logger.error('Failed to collect system metrics:', error);
    }
  }

  /**
   * 计算CPU使用率
   */
  calculateCpuUsage() {
    const cpus = os.cpus();
    let totalIdle = 0;
    let totalTick = 0;

    cpus.forEach(cpu => {
      for (const type in cpu.times) {
        totalTick += cpu.times[type];
      }
      totalIdle += cpu.times.idle;
    });

    const idle = totalIdle / cpus.length;
    const total = totalTick / cpus.length;
    const usage = 100 - ~~(100 * idle / total);

    return Math.max(0, Math.min(100, usage));
  }

  /**
   * 收集存储指标
   */
  async collectStorageMetrics() {
    try {
      const dataPath = process.env.DATA_PATH || './data';
      const stats = await this.getDirectorySize(dataPath);
      
      // 获取磁盘空间信息（简化版本）
      const diskSpace = await this.getDiskSpace();
      
      this.metrics.storage = {
        used: stats.size,
        files: stats.files,
        directories: stats.directories,
        disk: diskSpace
      };
    } catch (error) {
      logger.error('Failed to collect storage metrics:', error);
    }
  }

  /**
   * 获取目录大小
   */
  async getDirectorySize(dirPath) {
    let totalSize = 0;
    let fileCount = 0;
    let dirCount = 0;

    const calculateSize = async (currentPath) => {
      try {
        const stats = await fs.promises.stat(currentPath);
        
        if (stats.isDirectory()) {
          dirCount++;
          const files = await fs.promises.readdir(currentPath);
          
          for (const file of files) {
            await calculateSize(path.join(currentPath, file));
          }
        } else {
          fileCount++;
          totalSize += stats.size;
        }
      } catch (error) {
        // 忽略无法访问的文件
      }
    };

    if (fs.existsSync(dirPath)) {
      await calculateSize(dirPath);
    }

    return {
      size: totalSize,
      files: fileCount,
      directories: dirCount
    };
  }

  /**
   * 获取磁盘空间信息
   */
  async getDiskSpace() {
    try {
      // 在Windows上使用不同的方法
      if (process.platform === 'win32') {
        return await this.getWindowsDiskSpace();
      } else {
        return await this.getUnixDiskSpace();
      }
    } catch (error) {
      logger.error('Failed to get disk space:', error);
      return { total: 0, free: 0, used: 0, percentage: 0 };
    }
  }

  /**
   * 获取Windows磁盘空间
   */
  async getWindowsDiskSpace() {
    const { execSync } = require('child_process');
    try {
      const output = execSync('wmic logicaldisk get size,freespace,caption', { encoding: 'utf8' });
      const lines = output.split('\n').filter(line => line.trim());
      
      // 简化处理，取第一个磁盘
      if (lines.length > 1) {
        const parts = lines[1].trim().split(/\s+/);
        if (parts.length >= 3) {
          const free = parseInt(parts[1]) || 0;
          const total = parseInt(parts[2]) || 0;
          const used = total - free;
          
          return {
            total,
            free,
            used,
            percentage: total > 0 ? (used / total) * 100 : 0
          };
        }
      }
    } catch (error) {
      logger.error('Failed to get Windows disk space:', error);
    }
    
    return { total: 0, free: 0, used: 0, percentage: 0 };
  }

  /**
   * 获取Unix磁盘空间
   */
  async getUnixDiskSpace() {
    const { execSync } = require('child_process');
    try {
      const output = execSync('df -h .', { encoding: 'utf8' });
      const lines = output.split('\n');
      
      if (lines.length > 1) {
        const parts = lines[1].split(/\s+/);
        if (parts.length >= 6) {
          const total = this.parseSize(parts[1]);
          const used = this.parseSize(parts[2]);
          const free = this.parseSize(parts[3]);
          
          return {
            total,
            used,
            free,
            percentage: total > 0 ? (used / total) * 100 : 0
          };
        }
      }
    } catch (error) {
      logger.error('Failed to get Unix disk space:', error);
    }
    
    return { total: 0, free: 0, used: 0, percentage: 0 };
  }

  /**
   * 解析大小字符串（如 "1.5G" -> bytes）
   */
  parseSize(sizeStr) {
    const units = { K: 1024, M: 1024**2, G: 1024**3, T: 1024**4 };
    const match = sizeStr.match(/^(\d+(?:\.\d+)?)([KMGT]?)$/);
    
    if (match) {
      const value = parseFloat(match[1]);
      const unit = match[2];
      return Math.round(value * (units[unit] || 1));
    }
    
    return 0;
  }

  /**
   * 记录请求指标
   */
  recordRequest(responseTime, success = true) {
    this.metrics.requests.total++;
    
    if (success) {
      this.metrics.requests.successful++;
    } else {
      this.metrics.requests.failed++;
    }

    // 记录响应时间
    this.requestTimes.push({
      time: responseTime,
      timestamp: Date.now()
    });

    // 计算平均响应时间
    this.updateAverageResponseTime();

    // 检查慢请求
    if (responseTime > this.alertThresholds.responseTime) {
      logger.warn(`Slow request detected: ${responseTime}ms`);
    }
  }

  /**
   * 记录数据库查询指标
   */
  recordDatabaseQuery(queryTime, isSlowQuery = false) {
    this.metrics.database.totalQueries++;
    
    if (isSlowQuery) {
      this.metrics.database.slowQueries++;
    }

    this.queryTimes.push({
      time: queryTime,
      timestamp: Date.now()
    });

    this.updateAverageQueryTime();
  }

  /**
   * 更新数据库连接数
   */
  updateDatabaseConnections(activeConnections) {
    this.metrics.database.activeConnections = activeConnections;
  }

  /**
   * 更新平均响应时间
   */
  updateAverageResponseTime() {
    if (this.requestTimes.length === 0) return;

    const totalTime = this.requestTimes.reduce((sum, req) => sum + req.time, 0);
    this.metrics.requests.averageResponseTime = totalTime / this.requestTimes.length;
  }

  /**
   * 更新平均查询时间
   */
  updateAverageQueryTime() {
    if (this.queryTimes.length === 0) return;

    const totalTime = this.queryTimes.reduce((sum, query) => sum + query.time, 0);
    this.metrics.database.averageQueryTime = totalTime / this.queryTimes.length;
  }

  /**
   * 清理旧的指标数据
   */
  cleanupOldMetrics() {
    const fiveMinutesAgo = Date.now() - (5 * 60 * 1000);
    
    // 清理5分钟前的请求时间数据
    this.requestTimes = this.requestTimes.filter(req => req.timestamp > fiveMinutesAgo);
    this.queryTimes = this.queryTimes.filter(query => query.timestamp > fiveMinutesAgo);

    // 重新计算平均值
    this.updateAverageResponseTime();
    this.updateAverageQueryTime();
  }

  /**
   * 检查警告阈值
   */
  checkAlertThresholds() {
    const alerts = [];

    // 内存使用率检查
    if (this.metrics.memory.percentage > this.alertThresholds.memoryUsage) {
      alerts.push({
        type: 'memory',
        message: `High memory usage: ${this.metrics.memory.percentage.toFixed(1)}%`,
        value: this.metrics.memory.percentage,
        threshold: this.alertThresholds.memoryUsage
      });
    }

    // CPU使用率检查
    if (this.metrics.cpu.usage > this.alertThresholds.cpuUsage) {
      alerts.push({
        type: 'cpu',
        message: `High CPU usage: ${this.metrics.cpu.usage.toFixed(1)}%`,
        value: this.metrics.cpu.usage,
        threshold: this.alertThresholds.cpuUsage
      });
    }

    // 存储使用率检查
    if (this.metrics.storage.disk && this.metrics.storage.disk.percentage > this.alertThresholds.storageUsage) {
      alerts.push({
        type: 'storage',
        message: `High storage usage: ${this.metrics.storage.disk.percentage.toFixed(1)}%`,
        value: this.metrics.storage.disk.percentage,
        threshold: this.alertThresholds.storageUsage
      });
    }

    // 记录警告
    alerts.forEach(alert => {
      logger.warn('Performance Alert:', alert);
    });

    return alerts;
  }

  /**
   * 获取当前指标
   */
  getMetrics() {
    return {
      ...this.metrics,
      uptime: Date.now() - this.startTime,
      timestamp: new Date().toISOString()
    };
  }

  /**
   * 获取性能报告
   */
  getPerformanceReport() {
    const metrics = this.getMetrics();
    
    return {
      summary: {
        uptime: this.formatUptime(metrics.uptime),
        totalRequests: metrics.requests.total,
        successRate: metrics.requests.total > 0 ? 
          ((metrics.requests.successful / metrics.requests.total) * 100).toFixed(2) + '%' : '0%',
        averageResponseTime: metrics.requests.averageResponseTime.toFixed(2) + 'ms',
        memoryUsage: metrics.memory.percentage.toFixed(1) + '%',
        cpuUsage: metrics.cpu.usage.toFixed(1) + '%'
      },
      details: metrics,
      alerts: this.checkAlertThresholds()
    };
  }

  /**
   * 格式化运行时间
   */
  formatUptime(uptime) {
    const seconds = Math.floor(uptime / 1000);
    const minutes = Math.floor(seconds / 60);
    const hours = Math.floor(minutes / 60);
    const days = Math.floor(hours / 24);

    if (days > 0) {
      return `${days}天 ${hours % 24}小时 ${minutes % 60}分钟`;
    } else if (hours > 0) {
      return `${hours}小时 ${minutes % 60}分钟`;
    } else if (minutes > 0) {
      return `${minutes}分钟 ${seconds % 60}秒`;
    } else {
      return `${seconds}秒`;
    }
  }

  /**
   * 重置指标
   */
  resetMetrics() {
    this.metrics.requests = {
      total: 0,
      successful: 0,
      failed: 0,
      averageResponseTime: 0
    };
    
    this.metrics.database.totalQueries = 0;
    this.metrics.database.averageQueryTime = 0;
    this.metrics.database.slowQueries = 0;
    
    this.requestTimes = [];
    this.queryTimes = [];
    this.startTime = Date.now();
  }

  /**
   * 设置警告阈值
   */
  setAlertThresholds(thresholds) {
    this.alertThresholds = { ...this.alertThresholds, ...thresholds };
  }
}

// 创建全局性能监控实例
const performanceMonitor = new PerformanceMonitor();

module.exports = {
  PerformanceMonitor,
  performanceMonitor
};